;**********************DVM3 program******************
;	4MHz-es c1ock-ra iródott
	Errorlevel	0,-302
	Title 	DVM3
	List	X=on
	List	C=132
	List	N=94
	processor	16F882
	radix	hex
#include <p16F882.inc>
	__CONFIG    _CONFIG1, _LVP_OFF & _FCMEN_OFF & _IESO_OFF & _BOR_OFF & _CPD_OFF & _CP_OFF & _MCLRE_OFF & _PWRTE_OFF & _WDT_OFF & _INTRC_OSC_NOCLKOUT
	__CONFIG    _CONFIG2, _WRT_OFF & _BOR21V

;-------------------------------------------------------------------- 
;Register definitions 
;-------------------------------------------------------------------- 
	CBLOCK 0x20
;------------------------------------------------------------------------------

; A/D átalakítás
VEREDL, VEREDH          ; feszültségmérés eredménye
IEREDL, IEREDH          ; árammérés eredménye

Digit:4					;kiírandószám 4 digiten, a negyedik digit az állapotledek

; 16 bites átalakítás BCDre
BCDvalH
BCDvalM
BCDvalL
MCount
NumbHi
NumbLo
temp

FeszAram				;0 feszültség 1 áramkijelzés

count1					;számláló
wtreg1,wtreg0,wtreg2	;varakozo hurkok regiszterei

	ENDC
;------------------------------------------------------------------------------
; PORT kivezetések
;
opcioreg	equ	b'01001111'	;rbpu en. int rise, rtcc int.
					;presc. wdt, presc.=lll			
iranya		equ	b'11111111' ; bemenet
iranyb		equ	b'00100000' ; kimenet, B5 bemenet
iranyc		equ	b'00000000' ; kimenet
iranye		equ	b'11111111' ; bemenet
;-------------------------------------------------------------------- 
;BITEK 
;-------------------------------------------------------------------- 
#define carry 	STATUS,C 
#define zero 	STATUS,Z
#DEFINE rtcc	TMR0
#DEFINE CY		STATUS,C

JNC	MACRO	addr		;jump if carry bit is not set 
	btfss	3,0
	goto	addr
	ENDM

JC  MACRO  addr			;jump if carry bit is set 
	btfsc 3,0
	goto addr
	ENDM

JZ  MACRO  addr			;jump if zero bit is set 
	btfsc 3,2
	goto addr
	ENDM

CLC MACRO 				;clear carry bit
	bcf   3,0
	ENDM

JNZ	MACRO	ADDR
	BTFSS 	3,2
	GOTO	ADDR
	ENDM

MOV	MACRO	REG1,REG2
	MOVF	REG2,W
	MOVWF 	REG1
	ENDM

;------- Program----------------------------------------------------- 
	ORG	0000
	clrf	INTCON
	clrwdt
	clrf	PCLATH
	goto INIMAIN
;-------[ I N T E R R U P T    R U T I N ]---------------------------
	ORG 	0x004 

	retfie		;INTERRUPT VÉGE
;--------------------------------------------------------------------

INIMAIN
	banksel PORTA
	clrf	PORTA
	clrf	PORTB
	clrf	PORTC
	clrf	PORTE
	banksel	WPUB
	movlw	b'11111111'	;felhúzóellenállások bekapcsolva
	movwf	WPUB
	banksel	OPTION_REG
	movlw	opcioreg	
	movwf	OPTION_REG	
	clrf	INTCON		;megszakítás tiltva 
	banksel TRISE
	movlw	iranye
	movwf	TRISE
	movlw	iranyc
	movwf	TRISC
	movlw	iranyb
	movwf	TRISB		;portb iranyok beallitasa
	movlw	iranya
	movwf	TRISA		;porta iranyok beallitasa
	banksel ANSEL	
	movlw	b'00011111'
	movwf	ANSEL		;porta analog
	banksel ADCON1
	movlw	b'10010000' ;
	movwf	ADCON1		;jobbra igazítva, A3-Vss referencia
	banksel	ADCON0	
	banksel	SSPCON2
	clrf	SSPCON2
	clrf	PIE1
	clrf	PIE2
	banksel ANSELH
	clrf	ANSELH
	banksel	TMR1L
	clrf	TMR1L
	clrf	TMR1H
	clrf	T1CON		
	clrf	T2CON		
	clrf	SSPCON
	clrf	CCP1CON
	clrf	CCP2CON
	clrf	FeszAram

;-------[ ITT KEZDÖDIK A PROGRAM ]-----------
START
	movlw	B'00001111'	;PORTB alapállapot
	movwf	PORTB

	movlw	.5		;bekapcs után kb 1 sec várakozás
	movwf	count1		;hogy a tápfeszek tutira beálljanak
	movlw	.200		;200 msec várakozás
	call	WAIT		
	decfsz	count1
	goto	START+4
	clrf	Digit		;kijelzendő szám törlés
	clrf	Digit+1
	clrf	Digit+2
	clrf	Digit+3
	
MAIN
	movlw	.16		;minden 16-dik ciklusban mér
	movwf	count1
	
MAIN2
	bsf	PORTB,3		;digit kikapcsolás
	movfw 	Digit		;kiirandó szám betölt
	call	LedTable	;BCD 7 szegmens átalakítás
	movwf	PORTC		;kiírás
	btfsc	FeszAram,0	;ha árammérés
	bcf	PORTC,1		;decimális pont bekapcs
	bcf	PORTB,1		;megfelelő digitre kiir
    	movlw   .3
	call    WAIT		;3 msec mutatás

	bsf	PORTB,1		;ua mint előbb 2. digit
	movfw 	Digit+1
	call	LedTable
	movwf	PORTC
	btfss	FeszAram,0	;feszmérésnél Dp. bekapcs
	bcf	PORTC,1	
	bcf	PORTB,0
    	movlw   .3
	call    WAIT

	bsf	PORTB,0		;ua mint előbb 3. digit
	movfw 	Digit+2
	call	LedTable
	movwf	PORTC
	bcf	PORTB,2
	movlw 	.3
	call 	WAIT

	bsf	PORTB,2		;a 4 digit helyére az állapotjelző LED-ek vannak kötve
	movfw 	Digit+3
	movwf	PORTC		;ezért nem kell BCD átalakítás
	bcf	PORTB,3
	movlw 	.3
	call 	WAIT

	decfsz	count1
	goto	MAIN2		;ezt csinálja amíg count1 0 nem lesz

	call 	ADINRA0		;feszmérés RA0-ra van kötve

	call	FESZKAPCS	;a megfelelő feszültség beállítás

	call	VAvaltas	;gomb vizsgálat

	btfsc	FeszAram,0	;ha árammérés
	call	ADINRA1		;akkor az áram az RA1-re van kötve

	CLC
	rrf	NumbHi		;a kapott eredményt oszjuk kettővel
	rrf	NumbLo		;így a kijelzendő szám 0-511 közé esik (0-50.0V ill. 0-5.00A)
	CLC

	call	HexBCD		;a 16 bites hexa számot BCD+re alakítjuk
				;háromjegyű számot kapunk
	MOVFW	BCDvalM		;a százasok
	ANDLW	0X0F
	MOVWF	Digit		;bekerülnek az első helyre
	MOVFW	BCDvalL		;az egyesek
	ANDLW	0X0F
	MOVWF	Digit+2		;bekerülnek az harmadik helyre
	MOVFW	BCDvalL
	SWAPF	BCDvalL,W	;a tizesek
	ANDLW	0X0F
	MOVWF	Digit+1		;bekerülnek az második helyre

	goto	MAIN		;itt pörög a végtelenségig


;
;------------------------------------------------------------------------------
;******************************* SZUBRUTINOK **********************************
;------------------------------------------------------------------------------
;
;-----------------------------------------------------------------------------
; Feszültség kapcsolás           B6  B7         
; a két bit vezérli a reléket    0   0   28V
;                                0   1   19V
;                                1   1   6V
;                                1   0   40V
FESZKAPCS
	CLC
	rrf	VEREDH		;a feszmérés eredményét osztom 4-gyel
	rrf	VEREDL
	CLC
	rrf	VEREDH
	rrf	VEREDL
	CLC
	rrf	VEREDL		;az eredmény a mért feszültség fele 0-255 tehát kb fél volt pontos
	CLC
	movfw	VEREDL		
	sublw	.150			;30V-nál vált
	JC	ALUL30V		;ugrás ha alatta van
	bs	PORTB,6		;relék állítása
	bc	PORTB,7
;Szegmensek   eafbgcDd
	movlw	B'10111011'	;ledek beállítása
	movwf	Digit+3
	return

ALUL30V
	movfw	VEREDL
	sublw	.100		;mint előbb de 20V
	JC	ALUL20V
	bcf	PORTB,6
	bcf	PORTB,7
	movlw	B'11011011'
	movwf	Digit+3
	return

ALUL20V
	movfw	VEREDL
	sublw	.15
	JC	ALUL3V		;3V alatt, vagy rövidzár esetén
	bcf	PORTB,6
	bsf	PORTB,7
	movlw	B'11111010'
	movwf	Digit+3
	return

ALUL3V
	bsf	PORTB,6
	bsf	PORTB,7
	movlw	B'01111011'
	movwf	Digit+3
	return

;-----------------------------------------------------------------------------
; A/D átalakítás Volt
;
ADINRA0
	movlw	0x41		;AD beállítás RA0
	movwf   ADCON0 
	movlw	1		;várás 10uS
	call	DELAY10
	bsf	ADCON0,GO_DONE	;konverzió indul
A0TOV
	btfsc	ADCON0,GO_DONE	;ha végzett tovább
	goto	A0TOV
	
	MOV	VEREDH,ADRESH	;eredmény felső bájt
	banksel	ADRESL
	movfw	ADRESL  			
	banksel	ADRESH
	movwf	VEREDL		;eredmény alsó bájt
	MOV	NumbLo,VEREDL	;BCD átalakításhoz készít
	MOV	NumbHi,VEREDH

	return

;-----------------------------------------------------------------------------
; A/D átalakítás Amper
;
ADINRA1
	movlw	0x45		;mint előbb de RA1
	movwf	ADCON0 
	movlw	1              
	call	DELAY10
	bsf	ADCON0,GO_DONE 
A1TOV
	btfsc	ADCON0,GO_DONE 
	goto	A1TOV
	
	MOV	IEREDH,ADRESH	;árammérés eredménye
	banksel	ADRESL
	movfw	ADRESL  			
	banksel	ADRESH
	movwf	IEREDL    
	MOV	NumbLo,IEREDL	;ha árammérés volt felülírja a feszmérés eredményét
	MOV	NumbHi,IEREDH
	bsf	Digit+3,2	;a ledek beállítása
	bcf	Digit+3,3
	return

;-----------------------------------------------------------------------------
; Feszültség/Áram váltás
;
VAvaltas
	btfsc	PORTB,5			;gomb nyomva?
	return				;nem -> vissza
	movfw	FeszAram		;igen -> váltás
	xorlw	B'00000001'
	movwf	FeszAram
	return	 


;------------------------------------------------------------------------------
; BCD 7 szegmens dekódolás
;
LedTable
        addwf   PCL, F          ;add to PC low
;Szegmensek       eafbgcDd
        retlw   B'00001010'     ;led drive for 0
        retlw   B'11101011'     ;led drive for 1
        retlw   B'00100110'     ;led drive for 2
        retlw   B'10100010'     ;led drive for 3
        retlw   B'11000011'     ;led drive for 4
        retlw   B'10010010'     ;led drive for 5
        retlw   B'00010010'     ;led drive for 6
        retlw   B'10101011'     ;led drive for 7
        retlw   B'00000010'     ;led drive for 8
        retlw   B'10000010'     ;led drive for 9
        retlw   B'00000011'     ;led drive for A
        retlw   B'10111111'     ;led drive for felülvonás
        retlw   B'11110111'     ;led drive for közép
        retlw   B'11111110'     ;led drive for alulvonás
        retlw   B'00010110'     ;led drive for E
        retlw   B'00010111'     ;led drive for F

;------[ WAIT rutin ]------------------------------------------------ 
;	Ez a rutin N msec-ot vár, ahol N a W regiszterben van. 
;	Közben törli a watchdogot. 4 MHz-es clock-ra iródott
WAIT	movwf	wtreg1
	movlw	.248 
	movwf	wtreg0
WT1	clrwdt
	decfsz	wtreg0,f
	goto WT1
	movlw	.249
	movwf	wtreg0
	decfsz	wtreg1,f
	goto WT1
	return
;-------[ DELAY10 rutin ]-------------------------------------------- 
;	A rutin késleltetése: lOxN mikrosec, ahol N a W regiszterben van.
DELAY10
	movwf	wtreg0
DLY1	goto	$+1
	goto	$+1
	nop
	decfsz	wtreg0,f
	goto	DLY1
	return

;==================================================================== 
; Binary to BCD conversion routine
; 16 bit number to convert is in NumbHi, NumbLo
; result is set in BCDval HML
;
HexBCD    
   movlw d'16'
   movwf MCount
   clrf BCDvalH
   clrf BCDvalM
   clrf BCDvalL
   bcf STATUS,C

loop16    rlf NumbLo,F
   rlf NumbHi,F
   rlf BCDvalL,F
   rlf BCDvalM,F
   rlf BCDvalH,F

   decf MCount,F
   btfsc STATUS,Z
   return

adjDEC    movlw BCDvalL
   movwf FSR
   call adjBCD
   movlw BCDvalM
   movwf FSR
   call adjBCD
   movlw BCDvalH
   movwf FSR
   call adjBCD
   goto loop16

adjBCD   movlw d'3'
   addwf INDF,W
   movwf temp
   btfsc temp,3
   movwf INDF
   movlw 30h
   addwf INDF,W
   movwf temp
   btfsc temp,7
   movwf INDF
   return

	END